//
//  RandomIO.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/7/10.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef RandomIO_hpp
#define RandomIO_hpp

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
class RandomIO {
    
    
public:
    
    RandomIO(){
        
    }
    
    ~RandomIO(){
        
    }
    
    void TestRandomIO(){
        
        ifstream inf("sample2.txt");
        
        if (!inf) {
            //error
            cerr << "Uh oh, Sample.dat could not be opened for reading!" << endl;
            exit(1);
        }
        
        string strData;
        
        inf.seekg(5);
        getline(inf, strData);
        
        cout << strData << endl;
        
        inf.seekg(8, ios::cur);
        getline(inf, strData);
        cout << strData << endl;
        
        inf.seekg(-15, ios::end); // move 15 bytes before end of file
        // Get rest of the line and print it
        getline(inf, strData);
        cout << strData << endl;
        
        //        另外两个有用的函数是tellg（）和tellp（），它们返回文件指针的当前的位置。 这可用于确定文件的大小：
        //在文件最后当然返回文件大小(注意每一行后面还有1个\n)
        cout << inf.tellg();
        
        inf.close();
        
        //删除文件
//        remove("sample2.txt");
        
    }
    
//    使用fstream同时读取和写入文件
//    fstream类能够同时读取和写入文件 - 几乎！ 这里最大的警告是，不可能在任意读写之间切换。 一旦发生读或写，在两者之间切换的唯一方法是执行修改文件位置的操作（例如，seek）。 如果您实际上不想移动文件指针，则可以始终seek当前位置：否则会发生无法预知的问题
    
    void testIOftream(){
        
        fstream iofile("sample2.txt",ios::in | ios::out);
        
        if (!iofile)
        {
            // Print an error and exit
            cerr << "Uh oh, Sample.dat could not be opened!" << endl;
            exit(1);
        }
        
        char chChar;
        while (iofile.get(chChar)) {
            
            switch (chChar) {
                //发现元音
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u':
                case 'A':
                case 'E':
                case 'I':
                case 'O':
                case 'U':
                    
                    iofile.seekg(-1,ios::cur);//back one char
                    // Because we did a seek, we can now safely do a write, so
                    // let's write a # over the vowel
                    iofile << '#';
                    
                    // Now we want to go back to read mode so the next call
                    // to get() will perform correctly.  We'll seekg() to the current
                    // location because we don't want to move the file pointer.
                    iofile.seekg(iofile.tellg(), ios::beg);//相对开头偏移了tellg返回的位置
                   
                default:
                    break;
            }
            
        }
        
        
    }
    
    
};
/*
 其他有用的文件功能
 
 要删除文件，只需使用remove（）函数即可。
 此外，如果流当前打开，则is_open（）函数将返回true，否则返回false。
 
 规则：不要将地址写入文件。当您从磁盘读回其值时，最初位于这些地址的变量可能位于不同的地址，并且地址将无效。
 */


#endif /* RandomIO_hpp */
